/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package TimeRecording.business;

import TimeRecording.tables.AllocationOfHours;
import TimeRecording.tables.Employee;
import TimeRecording.tables.MonthlyTime;
import TimeRecording.tables.WeeklyTime;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.persistence.EntityManager;
import javax.persistence.Query;

/**
 *
 * @author david
 */
public class AccruedTime {

    /**
     * Get the accrued hours up to (but not including) the supplied date for the
     * supplied employee.
     *
     * @param entityManager
     * @param date
     * @param employee
     * @return
     */
    public static AllocationOfHours accruedToDate(EntityManager entityManager,
            Date date, Employee employee) {

        MonthlyTime lastMonthEnd = MonthlyTime.
                getLatestPreEndDate(entityManager, date, employee);

        if (lastMonthEnd == null) {
            return new AllocationOfHours();
        }

        Query query = entityManager.createNamedQuery(
                WeeklyTime.BY_EMPLOYEE_AND_DATE_RANGE);

        GregorianCalendar startCalendar = new GregorianCalendar();
        startCalendar.setTime(lastMonthEnd.getEndDate());
        startCalendar.add(GregorianCalendar.DATE, 1);

        GregorianCalendar endCalendar = new GregorianCalendar();
        endCalendar.setTime(date);
        startCalendar.add(GregorianCalendar.DATE, -1);
        
        query.setParameter("employeeId", employee.getEmployeeId());
        query.setParameter("startDate", DaisyChainUtilities.
                firstDayOfWeek(startCalendar).getTime());
        query.setParameter("endDate", DaisyChainUtilities.
                firstDayOfWeek(endCalendar).getTime());

        AllocationOfHours accruedHours = lastMonthEnd.getRevisedAllocation();

        Collection<WeeklyTime> weeksForPeriod = query.getResultList();

        while (!startCalendar.after(endCalendar)) {

            // Find the weekly time record for the chosen date
            WeeklyTime chosenWeek = null;
            for (WeeklyTime week : weeksForPeriod) {
                if (week.inRange(startCalendar)) {
                    chosenWeek = week;
                    break;
                }
            }

            if (chosenWeek != null) {
                AllocationOfHours dailyFigures =
                        chosenWeek.getDailyFigures(startCalendar);
                accruedHours.add(dailyFigures);
            }

            startCalendar.add(GregorianCalendar.DATE, 1);
        }

        return accruedHours;
    }
}
